package app.caretrack.model;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.OrderBy;
import javax.persistence.Table;

@Entity
@Table(name = "Machines")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@NamedQueries({ @NamedQuery(name = "findAllMachine", query = "SELECT m FROM Machine m") })
public class Machine extends NamedBaseModel {

    private String chassiId;

    private MachineModel machineModel;

    private MachineDevice machineDevice;

    private List<MachineWearPart> wearPartList;

    private MachineConfig machineConfig;

    private List<MachinePosition> machinePositionList;

    private MachinePosition latestMachinePosition;

    private ServicePackage servicePackage;

    public String getChassiId() {
        return this.chassiId;
    }

    public void setChassiId(String chassiId) {
        this.chassiId = chassiId;
    }

    @ManyToOne(fetch = FetchType.EAGER, optional = false)
    public MachineModel getMachineModel() {
        return this.machineModel;
    }

    public void setMachineModel(MachineModel machineModel) {
        this.machineModel = machineModel;
    }

    @OneToOne(fetch = FetchType.LAZY)
    public MachineDevice getMachineDevice() {
        return this.machineDevice;
    }

    public void setMachineDevice(MachineDevice machineDevice) {
        this.machineDevice = machineDevice;
    }

    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.REFRESH)
    @JoinTable(name = "Machines_WearParts", inverseJoinColumns = @JoinColumn(name = "WearPart_Id"), joinColumns = @JoinColumn(name = "Machine_Id"))
    public List<MachineWearPart> getWearPartList() {
        return this.wearPartList;
    }

    public void setWearPartList(List<MachineWearPart> wearPartList) {
        this.wearPartList = wearPartList;
    }

    @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.REMOVE)
    public MachineConfig getMachineConfig() {
        return this.machineConfig;
    }

    public void setMachineConfig(MachineConfig machineConfig) {
        this.machineConfig = machineConfig;
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "machine", cascade = CascadeType.REMOVE)
    @OrderBy("msgReceivedTimestamp DESC")
    public List<MachinePosition> getMachinePositionList() {
        if (this.machinePositionList == null) {
            this.machinePositionList = new ArrayList<MachinePosition>();
        }
        return this.machinePositionList;
    }

    public void setMachinePositionList(List<MachinePosition> machinePositionList) {
        this.machinePositionList = machinePositionList;
    }

    @OneToOne(fetch = FetchType.EAGER)
    public MachinePosition getLatestMachinePosition() {
        return this.latestMachinePosition;
    }

    public void setLatestMachinePosition(MachinePosition latestMachinePosition) {
        this.latestMachinePosition = latestMachinePosition;
    }

    @ManyToOne(fetch = FetchType.EAGER)
    public ServicePackage getServicePackage() {
        return this.servicePackage;
    }

    public void setServicePackage(ServicePackage servicePackage) {
        this.servicePackage = servicePackage;
    }

    @Override
    public String toString() {
        return super.toString() + ":" + this.chassiId;
    }
}
